home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / pyshared / PIL / ImImagePlugin.py < prev    next >
Text File  |  2006-12-03  |  10KB  |  336 lines

  1. #
  2. # The Python Imaging Library.
  3. # $Id: ImImagePlugin.py 2285 2005-02-07 23:52:14Z fredrik $
  4. #
  5. # IFUNC IM file handling for PIL
  6. #
  7. # history:
  8. # 1995-09-01 fl   Created.
  9. # 1997-01-03 fl   Save palette images
  10. # 1997-01-08 fl   Added sequence support
  11. # 1997-01-23 fl   Added P and RGB save support
  12. # 1997-05-31 fl   Read floating point images
  13. # 1997-06-22 fl   Save floating point images
  14. # 1997-08-27 fl   Read and save 1-bit images
  15. # 1998-06-25 fl   Added support for RGB+LUT images
  16. # 1998-07-02 fl   Added support for YCC images
  17. # 1998-07-15 fl   Renamed offset attribute to avoid name clash
  18. # 1998-12-29 fl   Added I;16 support
  19. # 2001-02-17 fl   Use 're' instead of 'regex' (Python 2.1) (0.7)
  20. # 2003-09-26 fl   Added LA/PA support
  21. #
  22. # Copyright (c) 1997-2003 by Secret Labs AB.
  23. # Copyright (c) 1995-2001 by Fredrik Lundh.
  24. #
  25. # See the README file for information on usage and redistribution.
  26. #
  27.  
  28.  
  29. __version__ = "0.7"
  30.  
  31. import re, string
  32. import Image, ImageFile, ImagePalette
  33.  
  34.  
  35. # --------------------------------------------------------------------
  36. # Standard tags
  37.  
  38. COMMENT = "Comment"
  39. DATE = "Date"
  40. EQUIPMENT = "Digitalization equipment"
  41. FRAMES = "File size (no of images)"
  42. LUT = "Lut"
  43. NAME = "Name"
  44. SCALE = "Scale (x,y)"
  45. SIZE = "Image size (x*y)"
  46. MODE = "Image type"
  47.  
  48. TAGS = { COMMENT:0, DATE:0, EQUIPMENT:0, FRAMES:0, LUT:0, NAME:0,
  49.          SCALE:0, SIZE:0, MODE:0 }
  50.  
  51. OPEN = {
  52.     # ifunc93/p3cfunc formats
  53.     "0 1 image": ("1", "1"),
  54.     "L 1 image": ("1", "1"),
  55.     "Greyscale image": ("L", "L"),
  56.     "Grayscale image": ("L", "L"),
  57.     "RGB image": ("RGB", "RGB;L"),
  58.     "RLB image": ("RGB", "RLB"),
  59.     "RYB image": ("RGB", "RLB"),
  60.     "B1 image": ("1", "1"),
  61.     "B2 image": ("P", "P;2"),
  62.     "B4 image": ("P", "P;4"),
  63.     "X 24 image": ("RGB", "RGB"),
  64.     "L 32 S image": ("I", "I;32"),
  65.     "L 32 F image": ("F", "F;32"),
  66.     # old p3cfunc formats
  67.     "RGB3 image": ("RGB", "RGB;T"),
  68.     "RYB3 image": ("RGB", "RYB;T"),
  69.     # extensions
  70.     "LA image": ("LA", "LA;L"),
  71.     "RGBA image": ("RGBA", "RGBA;L"),
  72.     "RGBX image": ("RGBX", "RGBX;L"),
  73.     "CMYK image": ("CMYK", "CMYK;L"),
  74.     "YCC image": ("YCbCr", "YCbCr;L"),
  75. }
  76.  
  77. # ifunc95 extensions
  78. for i in ["8", "8S", "16", "16S", "32", "32F"]:
  79.     OPEN["L %s image" % i] = ("F", "F;%s" % i)
  80.     OPEN["L*%s image" % i] = ("F", "F;%s" % i)
  81. for i in ["16", "16B"]:
  82.     OPEN["L %s image" % i] = ("I;%s" % i, "I;%s" % i)
  83.     OPEN["L*%s image" % i] = ("I;%s" % i, "I;%s" % i)
  84. for i in ["32S"]:
  85.     OPEN["L %s image" % i] = ("I", "I;%s" % i)
  86.     OPEN["L*%s image" % i] = ("I", "I;%s" % i)
  87. for i in range(2, 33):
  88.     OPEN["L*%s image" % i] = ("F", "F;%s" % i)
  89.  
  90.  
  91. # --------------------------------------------------------------------
  92. # Read IM directory
  93.  
  94. split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
  95.  
  96. def number(s):
  97.     try:
  98.         return int(s)
  99.     except ValueError:
  100.         return float(s)
  101.  
  102. ##
  103. # Image plugin for the IFUNC IM file format.
  104.  
  105. class ImImageFile(ImageFile.ImageFile):
  106.  
  107.     format = "IM"
  108.     format_description = "IFUNC Image Memory"
  109.  
  110.     def _open(self):
  111.  
  112.         # Quick rejection: if there's not an LF among the first
  113.         # 100 bytes, this is (probably) not a text header.
  114.  
  115.         if not "\n" in self.fp.read(100):
  116.             raise SyntaxError, "not an IM file"
  117.         self.fp.seek(0)
  118.  
  119.         n = 0
  120.  
  121.         # Default values
  122.         self.info[MODE] = "L"
  123.         self.info[SIZE] = (512, 512)
  124.         self.info[FRAMES] = 1
  125.  
  126.         self.rawmode = "L"
  127.  
  128.         while 1:
  129.  
  130.             s = self.fp.read(1)
  131.  
  132.             # Some versions of IFUNC uses \n\r instead of \r\n...
  133.             if s == "\r":
  134.                 continue
  135.  
  136.             if not s or s[0] == chr(0) or s[0] == chr(26):
  137.                 break
  138.  
  139.             # FIXME: this may read whole file if not a text file
  140.             s = s + self.fp.readline()
  141.  
  142.             if len(s) > 100:
  143.                 raise SyntaxError, "not an IM file"
  144.  
  145.             if s[-2:] == '\r\n':
  146.                 s = s[:-2]
  147.             elif s[-1:] == '\n':
  148.                 s = s[:-1]
  149.  
  150.             try:
  151.                 m = split.match(s)
  152.             except re.error, v:
  153.                 raise SyntaxError, "not an IM file"
  154.  
  155.             if m:
  156.  
  157.                 k, v = m.group(1,2)
  158.  
  159.                 # Convert value as appropriate
  160.                 if k in [FRAMES, SCALE, SIZE]:
  161.                     v = string.replace(v, "*", ",")
  162.                     v = tuple(map(number, string.split(v, ",")))
  163.                     if len(v) == 1:
  164.                         v = v[0]
  165.                 elif k == MODE and OPEN.has_key(v):
  166.                     v, self.rawmode = OPEN[v]
  167.  
  168.                 # Add to dictionary. Note that COMMENT tags are
  169.                 # combined into a list of strings.
  170.                 if k == COMMENT:
  171.                     if self.info.has_key(k):
  172.                         self.info[k].append(v)
  173.                     else:
  174.                         self.info[k] = [v]
  175.                 else:
  176.                     self.info[k] = v
  177.  
  178.                 if TAGS.has_key(k):
  179.                     n = n + 1
  180.  
  181.             else:
  182.  
  183.                 raise SyntaxError, "Syntax error in IM header: " + s
  184.  
  185.         if not n:
  186.             raise SyntaxError, "Not an IM file"
  187.  
  188.         # Basic attributes
  189.         self.size = self.info[SIZE]
  190.         self.mode = self.info[MODE]
  191.  
  192.         # Skip forward to start of image data
  193.         while s and s[0] != chr(26):
  194.             s = self.fp.read(1)
  195.         if not s:
  196.             raise SyntaxError, "File truncated"
  197.  
  198.         if self.info.has_key(LUT):
  199.             # convert lookup table to palette or lut attribute
  200.             palette = self.fp.read(768)
  201.             greyscale = 1 # greyscale palette
  202.             linear = 1 # linear greyscale palette
  203.             for i in range(256):
  204.                 if palette[i] == palette[i+256] == palette[i+512]:
  205.                     if palette[i] != chr(i):
  206.                         linear = 0
  207.                 else:
  208.                     greyscale = 0
  209.             if self.mode == "L" or self.mode == "LA":
  210.                 if greyscale:
  211.                     if not linear:
  212.                         self.lut = map(ord, palette[:256])
  213.                 else:
  214.                     if self.mode == "L":
  215.                         self.mode = self.rawmode = "P"
  216.                     elif self.mode == "LA":
  217.                         self.mode = self.rawmode = "PA"
  218.                     self.palette = ImagePalette.raw("RGB;L", palette)
  219.             elif self.mode == "RGB":
  220.                 if not greyscale or not linear:
  221.                     self.lut = map(ord, palette)
  222.  
  223.         self.frame = 0
  224.  
  225.         self.__offset = offs = self.fp.tell()
  226.  
  227.         self.__fp = self.fp # FIXME: hack
  228.  
  229.         if self.rawmode[:2] == "F;":
  230.  
  231.             # ifunc95 formats
  232.             try:
  233.                 # use bit decoder (if necessary)
  234.                 bits = int(self.rawmode[2:])
  235.                 if bits not in [8, 16, 32]:
  236.                     self.tile = [("bit", (0,0)+self.size, offs,
  237.                                  (bits, 8, 3, 0, -1))]
  238.                     return
  239.             except ValueError:
  240.                 pass
  241.  
  242.         if self.rawmode in ["RGB;T", "RYB;T"]:
  243.             # Old LabEye/3PC files.  Would be very surprised if anyone
  244.             # ever stumbled upon such a file ;-)
  245.             size = self.size[0] * self.size[1]
  246.             self.tile = [("raw", (0,0)+self.size, offs, ("G", 0, -1)),
  247.                          ("raw", (0,0)+self.size, offs+size, ("R", 0, -1)),
  248.                          ("raw", (0,0)+self.size, offs+2*size, ("B", 0, -1))]
  249.         else:
  250.             # LabEye/IFUNC files
  251.             self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
  252.  
  253.     def seek(self, frame):
  254.  
  255.         if frame < 0 or frame >= self.info[FRAMES]:
  256.             raise EOFError, "seek outside sequence"
  257.  
  258.         if self.frame == frame:
  259.             return
  260.  
  261.         self.frame = frame
  262.  
  263.         if self.mode == "1":
  264.             bits = 1
  265.         else:
  266.             bits = 8 * len(self.mode)
  267.  
  268.         size = ((self.size[0] * bits + 7) / 8) * self.size[1]
  269.         offs = self.__offset + frame * size
  270.  
  271.         self.fp = self.__fp
  272.  
  273.         self.tile = [("raw", (0,0)+self.size, offs, (self.rawmode, 0, -1))]
  274.  
  275.     def tell(self):
  276.  
  277.         return self.frame
  278.  
  279. #
  280. # --------------------------------------------------------------------
  281. # Save IM files
  282.  
  283. SAVE = {
  284.     # mode: (im type, raw mode)
  285.     "1": ("0 1", "1"),
  286.     "L": ("Greyscale", "L"),
  287.     "LA": ("LA", "LA;L"),
  288.     "P": ("Greyscale", "P"),
  289.     "PA": ("LA", "PA;L"),
  290.     "I": ("L 32S", "I;32S"),
  291.     "I;16": ("L 16", "I;16"),
  292.     "I;16B": ("L 16B", "I;16B"),
  293.     "F": ("L 32F", "F;32F"),
  294.     "RGB": ("RGB", "RGB;L"),
  295.     "RGBA": ("RGBA", "RGBA;L"),
  296.     "RGBX": ("RGBX", "RGBX;L"),
  297.     "CMYK": ("CMYK", "CMYK;L"),
  298.     "YCbCr": ("YCC", "YCbCr;L")
  299. }
  300.  
  301. def _save(im, fp, filename, check=0):
  302.  
  303.     try:
  304.         type, rawmode = SAVE[im.mode]
  305.     except KeyError:
  306.         raise ValueError, "Cannot save %s images as IM" % im.mode
  307.  
  308.     try:
  309.         frames = im.encoderinfo["frames"]
  310.     except KeyError:
  311.         frames = 1
  312.  
  313.     if check:
  314.         return check
  315.  
  316.     fp.write("Image type: %s image\r\n" % type)
  317.     if filename:
  318.         fp.write("Name: %s\r\n" % filename)
  319.     fp.write("Image size (x*y): %d*%d\r\n" % im.size)
  320.     fp.write("File size (no of images): %d\r\n" % frames)
  321.     if im.mode == "P":
  322.         fp.write("Lut: 1\r\n")
  323.     fp.write("\000" * (511-fp.tell()) + "\032")
  324.     if im.mode == "P":
  325.         fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
  326.     ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
  327.  
  328. #
  329. # --------------------------------------------------------------------
  330. # Registry
  331.  
  332. Image.register_open("IM", ImImageFile)
  333. Image.register_save("IM", _save)
  334.  
  335. Image.register_extension("IM", ".im")
  336.